package panels;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;

import panels.util.ActorTabbedPane;
import panels.util.DnDTabbedPane;
import panels.util.JFileChooserButton;
import sprites.Sprite;
import xml.Xml;

public class ActorCollectionPanel extends JPanel {
	/**
	 *
	 */
	private static final long	serialVersionUID = 1L;
	private DnDTabbedPane 		actorTabs;
	private JFileChooserButton saveActorButton;


	/**
	 * Create the panel.
	 */
	public ActorCollectionPanel() {
		setBorder(new TitledBorder(null, "Actors", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		setLayout(new BorderLayout(0, 0));
		setLayout(new BorderLayout(0, 0));

		JPanel headerPanel = new JPanel();
		add(headerPanel, BorderLayout.NORTH);
		headerPanel.setLayout(new BorderLayout(0, 0));

		JPanel orderPanel = new JPanel();
		orderPanel.setBorder(new TitledBorder(null, "Order", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		headerPanel.add(orderPanel, BorderLayout.CENTER);
		orderPanel.setLayout(new GridLayout(2, 1, 1, 0));

		JButton btnNewButton = new JButton("Add");
		orderPanel.add(btnNewButton);

		JButton btnNewButton_1 = new JButton("Del");
		btnNewButton_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int idx = actorTabs.getSelectedIndex();
				if (idx >= 0) {
					ActorPanel	A = (ActorPanel) getActorTabs().getComponentAt(idx);
					if (A!=null) {
						if (A.getSprite()!=null) {
							Sprite.all.remove(A.getSprite());
						}
						actorTabs.remove(idx);
					}
				}
			}
		});
		orderPanel.add(btnNewButton_1);

		JButton prevButton = new JButton("<=");
		prevButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int idx = actorTabs.getSelectedIndex();
				if (idx >= 0) {
					idx = (idx + actorTabs.getTabCount() - 1) % actorTabs.getTabCount();
					actorTabs.setSelectedIndex(idx);
				}
			}
		});

		JButton clearActorsButton = new JButton("Clear");
		clearActorsButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				getActorTabs().removeAll();
			}
		});
		orderPanel.add(clearActorsButton);
		orderPanel.add(prevButton);

		JButton nextButton = new JButton("=>");
		nextButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int idx = actorTabs.getSelectedIndex();
				if (idx >= 0) {
					idx = (idx + actorTabs.getTabCount() + 1) % actorTabs.getTabCount();
					actorTabs.setSelectedIndex(idx);
				}
			}
		});
		orderPanel.add(nextButton);

		JButton sortButton = new JButton("Sort");
		sortButton.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					printActorList();
					sortActorsByInit();
					printActorList();
				}
			}
		);
		orderPanel.add(sortButton);

		JPanel filePanel = new JPanel();
		headerPanel.add(filePanel, BorderLayout.NORTH);
		filePanel.setLayout(new GridLayout(0, 2, 0, 0));

		JPanel encounterPanel = new JPanel();
		filePanel.add(encounterPanel);
		encounterPanel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Encounter", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		encounterPanel.setLayout(new GridLayout(2, 1, 0, 0));

		JFileChooserButton loadEncounterButton = new JFileChooserButton();
		loadEncounterButton.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals(JFileChooserButton.SELECTED_FILE_PROPERTY)) {
					File	F = (File) evt.getNewValue();
					if (F!=null) {
						loadEncounter(F.getAbsolutePath());
					}
				}
			}
		});
		loadEncounterButton.setDialogButtonText("Open");
		loadEncounterButton.setButtonText("Load");
		encounterPanel.add(loadEncounterButton);

		JFileChooserButton saveEncounterButton = new JFileChooserButton();
		saveEncounterButton.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals(JFileChooserButton.SELECTED_FILE_PROPERTY)) {
					File	F = (File) evt.getNewValue();
					if (F!=null) {
						saveEncounter(F.getAbsolutePath());
					}
				}
			}
		});
		saveEncounterButton.setDialogButtonText("Save As");
		saveEncounterButton.setButtonText("Save");
		encounterPanel.add(saveEncounterButton);

		JPanel actorPanel = new JPanel();
		filePanel.add(actorPanel);
		actorPanel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Actor", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		actorPanel.setLayout(new GridLayout(0, 1, 0, 0));

		JFileChooserButton loadActorButton = new JFileChooserButton();
		loadActorButton.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals(JFileChooserButton.SELECTED_FILE_PROPERTY)) {
					ActorPanel A = getSelectedActor();
					if (A != null) {
						File	F = (File) evt.getNewValue();
						if (F!=null) {
							A.readFromFile(F.getAbsolutePath());
							getActorTabs().setTitleAt(getSelectedIndex(), A.getActorName().getText());
						}
					}
				}
			}
		});
		loadActorButton.setButtonText("Load");
		loadActorButton.setDialogButtonText("Open");
		actorPanel.add(loadActorButton);

		saveActorButton = new JFileChooserButton();
		saveActorButton.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName().equals(JFileChooserButton.SELECTED_FILE_PROPERTY)) {
					ActorPanel A = getSelectedActor();
					if (A != null) {
						File	F = (File) evt.getNewValue();
						if (F!=null) {
							A.writeToFile(F.getAbsolutePath());
						}
					}
				}
			}
		});
		saveActorButton.setButtonText("Save");
		saveActorButton.setDialogButtonText("Save As");
		actorPanel.add(saveActorButton);

		//
		// Add the listender to the new Actor button
		//
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				ActorPanel		panel = new ActorPanel();

				panel.setTabPanel(actorTabs);
				if (getActorTabs().getSelectedIndex()>=0) {
					panel.setCopy(getSelectedActor());
					panel.setName("Copy of " + getSelectedActor().getName());
				} else {
					panel.getActorName().setText("Actor" + getActorTabs().getTabCount() );
				}
				getActorTabs().addTab(panel.getActorName().getText(), panel);
				getActorTabs().setSelectedComponent(panel);
				System.out.println(panel.toXml());
			}
		});


		actorTabs = new DnDTabbedPane();
		actorTabs.setTabPlacement(ActorTabbedPane.RIGHT);
		actorTabs.setTabLayoutPolicy(ActorTabbedPane.SCROLL_TAB_LAYOUT);
		add(actorTabs);

	}


	public ActorPanel getSelectedActor() {
		return (ActorPanel) getActorTabs().getSelectedComponent();
	}

	public ActorPanel getActorAtIndex(int idx) {
		if (idx >= 0) {
			return (ActorPanel) this.getActorTabs().getComponentAt(idx);
		} else {
			return null;
		}
	}

	public int getSelectedIndex() {
		return this.getActorTabs().getSelectedIndex();
	}

	public int getNumberOfActors() {
		return this.getActorTabs().getTabCount();
	}

	public DnDTabbedPane getActorTabs() {
		return actorTabs;
	}

	public void swapActorsData(ActorPanel A1, ActorPanel A2) {
		//
		// Takes two ActorPanels and swaps their data.
		//
		ActorPanel	tmp = new ActorPanel();
		tmp.setCopy(A1);
		A1.setCopy(A2);
		A2.setCopy(tmp);
	}

	public void swapActors(int P1, int P2) {
		//
		// Takes two ActorPanels and swaps their data.
		//
		ActorPanel	A1 = getActorAtIndex(P1);
		ActorPanel	A2 = getActorAtIndex(P2);
		ActorPanel	A3 = new ActorPanel();

		A3.getActorName().setText("This is a temporary Actor");

		getActorTabs().setComponentAt(P1, A3);
		getActorTabs().setComponentAt(P2, A1);
		getActorTabs().setComponentAt(P1, A2);

		getActorTabs().setTitleAt(P1, A2.getActorName().getText());
		getActorTabs().setTitleAt(P2, A1.getActorName().getText());
	}


	public void sortActorsByInit() {
		int i, j;
		boolean	done = false;

		for(i=0; i<getNumberOfActors() - 1 && !done; i++) {
			done = true;
			for(j = i+1; j<getNumberOfActors(); j++) {
				ActorPanel	Ai = getActorAtIndex(i);
				ActorPanel	Aj = getActorAtIndex(j);
				int			Ii = Ai.getInitBox().getValue();
				int			Ij = Aj.getInitBox().getValue();
				int			Di = Ai.getDexBox().getValue();
				int			Dj = Aj.getDexBox().getValue();

				if (Ii < Ij) {
					swapActors(i,j);
					done = false;
				} else if (Ii == Ij) {
					if (Di < Dj) {
						swapActors(i, j);
						done = false;
					}
				}
			}
		}
	}

	public void printActorList() {
		int i;

		System.out.println("=====================================");
		for (i=0; i<getActorTabs().getTabCount(); i++) {
			ActorPanel A = getActorAtIndex(i);
			System.out.println("Actor " + i + " = " + A.getActorName().getText());
		}
		System.out.println("=====================================");

	}

	public void saveEncounter(String filename) {
		//
		// This will write the data to a file
		//
		if (filename!=null) {
			PrintWriter writer = null;
			try {
				writer = new PrintWriter(filename, "UTF-8");
				writer.println(toXml());
				writer.close();
			} catch (IOException ex) {
				System.err.println("Could not write Encounter to " + filename);
			} finally {
			   try { writer.close(); } catch (Exception ex) {}
			}
		}
	}

	public void loadEncounter(String filename) {
		//
		// This will read the actor information from a text file
		//
		   String content = null;
		   File file = new File(filename); //for ex foo.txt
		   try {
		       FileReader reader = new FileReader(file);
		       char[] chars = new char[(int) file.length()];
		       reader.read(chars);
		       content = new String(chars);
		       fromXml(content);
		       reader.close();
		   } catch (IOException e) {
		       e.printStackTrace();
		   }
	}

	public String toXml() {
		String		S = "";
		int 		i;
		ActorPanel	A;
		S += "<encounter>\n";
		S += "  <numberOfActors>" + getNumberOfActors() + "</numberOfActors>\n";
		S += "  <selectedIndex>" + getSelectedIndex() + "</selectedIndex>\n";
		S += "<allActors>\n";

		for(i=0; i<getNumberOfActors(); i++) {
			A = getActorAtIndex(i);
			S += "<actor_" + Integer.toString(i) + ">\n";
			S += A.toXml() + "\n";
			S += "</actor_" + Integer.toString(i) + ">\n";
		}
		S += "</allActors>\n";
		S += "</encounter>\n";
		return S;
	}

	public void fromXml(String xml) {
		String	content = Xml.getTag("encounter",xml);
		int		numberOfActors	= Integer.parseInt(Xml.getTag("numberOfActors",content));
		int		selectedIndex	= Integer.parseInt(Xml.getTag("selectedIndex",content));
		int		i;

		getActorTabs().removeAll();

		if (numberOfActors>0) {
			String	actors = Xml.getTag("allActors",content);
			String	Axml;
			String	Atag;
			ActorPanel	A[] = new ActorPanel[numberOfActors];

			for(i=0; i<numberOfActors; i++) {
				Atag = "actor_" + Integer.toString(i);
				Axml = Xml.getTag(Atag,actors);
				A[i] = new ActorPanel();
				A[i].fromXml(Axml);
			}

			//
			// Now the we have all the information we need, we should set all the actors
			//
			for(i=0; i<A.length; i++) {
				getActorTabs().addTab(A[i].getActorName().getText(), A[i]);
			}
		}

		if (selectedIndex >= 0) {
			getActorTabs().setSelectedIndex(selectedIndex);
		}

	}
}
